﻿#include "stdafx.h"
#include "Login.h"

Login::Login(QWidget *parent)
	: QDialog(parent)
{
	ui.setupUi(this);
    setAttribute(Qt::WA_TranslucentBackground, true);
    setAttribute(Qt::WA_NoSystemBackground, true);
    ui.stackedWidget->setAttribute(Qt::WA_TranslucentBackground, true);

    m_strHostAddress = "127.0.0.1";
    m_uPort = 60000;

    this->setFixedSize(430+12, 330+12);
#ifdef Q_OS_WIN32
    // 去掉窗口标题栏方式
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    // 设置标题
    //ui.titleLabel->setText("<b><font color=white>&nbsp;YY 0.1</font></b>");
    ui.titleLabel->setText("");
    setProperty("isWin32", true);
    this->setContentsMargins(6, 6, 6, 6);
#else
    setWindowFlags(Qt::WindowStaysOnTopHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint);
    ui.titleLabel->setText("");
    //setWindowTitle("Air");
    ui.minisizeSysButton->hide();
    ui.closeSysButton->hide();
    setProperty("isWin32", false);
    this->setContentsMargins(0, 0, 0, 0);
#endif

    ui.topVerticalSpacer->changeSize(430, 184, QSizePolicy::Fixed, QSizePolicy::Fixed);


    // 用户默认头像
    ui.portraitLabel->setScaledContents(true);
    setUserPortrait();
	ui.accountComboBox->lineEdit()->setPlaceholderText(tr("帐号"));
	ui.passwordEdit->setPlaceholderText(tr("密码"));
	//ui.passwordEdit->setStyleSheet("lineedit-password-character: 42;");


    //  用户名 QListWidget 处理
    m_listWidget = new QListWidget(this);
    ui.accountComboBox->setModel(m_listWidget->model());
    ui.accountComboBox->setView(m_listWidget);
    connect(m_listWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(listWidgetCurrentItemChanged(QListWidgetItem*, QListWidgetItem*)));
	connect(ui.accountComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(accountComboBoxItemChanged(int)));
	AccountComboStyledItemDelegate* accountWidgetStyledItemDelegate = new AccountComboStyledItemDelegate;
    m_listWidget->setItemDelegate(accountWidgetStyledItemDelegate);
	connect(accountWidgetStyledItemDelegate, SIGNAL(removeAccount(int)), this, SLOT(removeAccount(int)));
    //accountComboBoxItemChanged(0);

     // statusMenu用户在线显示状态弹出菜单
    m_statusMenu = new QMenu(this);
    m_statusMenu->addAction(QIcon(":/Resources/Status/Big/online.png"), tr("Online"));
    m_statusMenu->addSeparator();
    m_statusMenu->addAction(QIcon(":/Resources/Status/Big/away.png"), tr("Away"));
    m_statusMenu->addAction(QIcon(":/Resources/Status/Big/busy.png"), tr("Busy"));
    m_statusMenu->addSeparator();
    m_statusMenu->addAction(QIcon(":/Resources/Status/Big/offline.png"), tr("Offline"));
	//ui.statusButton->setMenu(statusMenu);
	//ui.statusButton->setIcon(QIcon(":/Resources/Status/Big/online.png"));

    // statusMenu用户在线显示状态弹出菜单圆角效果
	QPainterPath path;
    QRectF rect = QRectF(0 ,0, m_statusMenu->sizeHint().width(), m_statusMenu->sizeHint().height());
	path.addRoundedRect(rect, 2, 2);
	QPolygon polygon = path.toFillPolygon().toPolygon();		// 获得这个路径上的所有的点
	QRegion region(polygon);									// 根据这个点构造这个区域
    m_statusMenu->setMask(region);

    // 状态按钮
    QVBoxLayout* statusVerticalLayout = new QVBoxLayout();
    statusVerticalLayout->setObjectName(QStringLiteral("statusVerticalLayout"));
    statusVerticalLayout->setContentsMargins(0, 0, 0, 0);
    statusVerticalLayout->addStretch();
    QHBoxLayout* statusHorizontalLayout = new QHBoxLayout();
    statusHorizontalLayout->setSpacing(0);
    statusHorizontalLayout->setObjectName(QStringLiteral("statusHorizontalLayout"));
    QPushButton* statusButton = new QPushButton();
    statusButton->setObjectName(QStringLiteral("statusButton"));
    statusButton->setMinimumSize(QSize(16, 16));
    statusButton->setMaximumSize(QSize(16, 16));
    statusButton->setMenu(m_statusMenu);
    statusButton->setIcon(QIcon(":/Resources/Status/Big/online.png"));
    statusHorizontalLayout->addStretch();
    statusHorizontalLayout->addWidget(statusButton);
    statusVerticalLayout->addItem(statusHorizontalLayout);
    ui.portraitLabel->setLayout(statusVerticalLayout);

    // 登录动画
    /*QMovie *movie = new QMovie(":/LoginPanel/Resources/LoginPanel/loading.gif");
    ui.labGif->setMovie(movie);
    movie->start();
    movie->setSpeed(50);
    ui.labGif->setScaledContents(true);*/
    // socket
    m_socket = new QTcpSocket;
    connect(m_socket, SIGNAL(connected()), this, SLOT(socketConnected()));
    connect(m_socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
    connect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
    connect(&m_socketTimer, SIGNAL(timeout()), this, SLOT(socketTimeout()));

    // 载入用户缓存
    loadUsersData();
}

Login::~Login()
{
    QSqlDatabase::removeDatabase("default");
}

void Login::paintEvent(QPaintEvent* /*event*/)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing);

    QPainterPath path;
#ifdef Q_OS_WIN32
    path.addRoundedRect(this->rect(), 4, 4);

    p.fillRect(this->rect().left()+6, this->rect().top()+6, this->rect().width()-12, this->rect().height()-12, QColor(232, 236, 247));
    p.drawPixmap(6, 6, QPixmap(":/LoginPanel/Resources/LoginPanel/morning.jpg"));
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
#else
    path.addRect(this->rect());
    p.drawPixmap(0, 0, QPixmap(":/LoginPanel/Resources/LoginPanel/morning.jpg"));
#endif
}

#ifdef Q_OS_WIN32
bool Login::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
	if (eventType == "windows_generic_MSG")
	{
		MSG* msg = (MSG*)message;
		switch (msg->message)
		{
		case WM_NCHITTEST:
			{
				int xPos = GET_X_LPARAM(msg->lParam) - this->frameGeometry().x();
				int yPos = GET_Y_LPARAM(msg->lParam) - this->frameGeometry().y();
				QWidget* widget = this->childAt(xPos, yPos);
				if (widget == nullptr)
				{
					*result = HTCAPTION;
				}
                else if (widget->objectName() == "titleLabel" || widget->objectName() == "pageLogin" || widget->objectName() == "pageLogining"
                    || widget->objectName() == "pageStatus" || widget->objectName() == "profilePicture")
				{
					*result = HTCAPTION;
				}
				else
				{
					//qDebug() << widget->objectName();
					return false;
				}

				return true;
			}
			break;
		}
	}

	return false;
}
#endif

void Login::on_minisizeSysButton_clicked()
{
    this->showMinimized();
}

void Login::on_closeSysButton_clicked()
{
    qApp->quit();
    //close();
}

// 删除帐号时，弹出提示框，与用户进行交互，告知是否确定要删除此帐号的所有信息！
void Login::removeAccount(int index)
{
	//ui.accountComboBox->hidePopup();
	//QMessageBox::question(this, tr("remove account"), tr("are you sure to remove account?"), QMessageBox::Yes | QMessageBox::No,  QMessageBox::No);
	QMessageBox msgbox;
	msgbox.raise();
	msgbox.setWindowFlags(Qt::WindowStaysOnTopHint); 
	msgbox.setWindowTitle(tr("remove account"));
	msgbox.setText(tr("are you sure to remove account?"));
	msgbox.setIconPixmap(QPixmap(":/Resources/attention.png"));
	msgbox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
	msgbox.setDefaultButton(QMessageBox::No);
	if(msgbox.exec() == QMessageBox::Yes)
	{
		if (index == ui.accountComboBox->currentIndex())
		{
			ui.passwordEdit->setText("");
            setUserPortrait();
            ui.autoLoginCheck->setChecked(false);
            ui.rememberPwdCheck->setChecked(false);
		}
		ui.accountComboBox->removeItem(index);
	}
}

void Login::listWidgetCurrentItemChanged(QListWidgetItem* current, QListWidgetItem* previous)
{
	if (current != nullptr)
	{
		//qDebug("current: %s, Last: %s", current->text(), previous->text());
		//QString str =current->text();
		//qDebug("current: %s", qPrintable(current->text()));
		current->setSizeHint(QSize(10, 40));
		//QWidget *accountItem = listWidget->itemWidget(current);
		//if (accountItem != nullptr)
		//{
		//		QPushButton *button = accountItem->findChild<QPushButton *>(QStringLiteral("cstatusButton"));
		//		//accountItem->setVisible(false);
		//		//listWidget->setItemHidden(previous, true);
		//		//listWidget->setItemWidget(previous, nullptr);
		//		//accountItem->setHidden(true);
		//		//QTimer::singleShot(1, button, SLOT(show()));
		//		button->setVisible(true);
		//		//accountItem->hide();
		//	//accountItem->show();
		//}
	}
	if (previous != nullptr)
	{
		previous->setSizeHint(QSize(10, 25));
		//QWidget *accountItem = listWidget->itemWidget(previous);
		//if (accountItem != nullptr)
		//{
		//	QPushButton *button = accountItem->findChild<QPushButton *>(QStringLiteral("cstatusButton"));
		//	//accountItem->setVisible(false);
		//	//listWidget->setItemHidden(previous, true);
		//	//listWidget->setItemWidget(previous, nullptr);
		//	//accountItem->setHidden(true);
		//	//QTimer::singleShot(1, button, SLOT(hide()));
		//	button->setVisible(false);
		//	//accountItem->hide();
		//}
	}
}

void Login::accountComboBoxItemChanged(int index)
{
    QListWidgetItem* listItem = m_listWidget->item(index);
	if (listItem != nullptr)
    {
		//QString strAccount = listItem->data(Qt::DisplayRole).toString();		// 账号
		//QString strNickName = listItem->data(Qt::UserRole + 1).toString();	// 昵称
        QString strPwd = listItem->data(Qt::UserRole + 3).toString();               // 密码
        QPixmap pixmap = qvariant_cast<QPixmap>(listItem->data(Qt::UserRole + 2));      // 头像

        ui.passwordEdit->setText(strPwd);
        if (strPwd.isEmpty())
            ui.rememberPwdCheck->setChecked(false);
        else
            ui.rememberPwdCheck->setChecked(true);

        // 设置头像
        setUserPortrait(pixmap);
	}
}

void Login::on_signinButton_clicked()
{
    QString strUserName = ui.accountComboBox->lineEdit()->text();
    QString strPwd = ui.passwordEdit->text();
    if (strUserName.isEmpty() || strPwd.isEmpty())
    {
        return;
    }

    ui.stackedWidget->setCurrentIndex(1);
    m_socket->connectToHost(m_strHostAddress, m_uPort);
}

void Login::on_cancelSigninButton_clicked()
{
    // 用户主动取消登录
    if (m_socket->isOpen())
    {
        m_socket->close();
    }
}

void Login::socketConnected()
{
    QString strUserName = ui.accountComboBox->lineEdit()->text();
    //QString strPwd = ui.passwordEdit->text();
    m_socket->write((const char*)strUserName.toUtf8(), strUserName.length());
    //socket.write((const char*)strPwd.toUtf8(), strPwd.length());

    // Start the timer.
   m_socketTimer.start(15000);
}

void Login::socketDisconnected()
{
    if (m_socketTimer.isActive())
    {
         m_socketTimer.stop();
    }
    // 用户主动取消登录或登录超时?
    ui.stackedWidget->setCurrentIndex(0);
}

void Login::socketError(QAbstractSocket::SocketError /*socketErr*/)
{
    if (m_socketTimer.isActive())
    {
         m_socketTimer.stop();
    }
    //  发生错误
    ui.stackedWidget->setCurrentIndex(0);

    QMessageBox msgbox(this);
    msgbox.setWindowTitle("错误");
    //msgbox.setText("无法登录的原因：\r\n1.帐号输入错误或不存在\r\n2.密码错误，请检查是否区分大小写");
    msgbox.setText(m_socket->errorString());
    msgbox.setIcon(QMessageBox::Critical);
    msgbox.exec();
}

 void Login::socketReadyRead()
 {
     // Restart the timer by calling start.
     //socketTimer.start(15000);
     m_socketTimer.stop();

     QByteArray buffer =  m_socket->readAll();
     QString strUserName = ui.accountComboBox->lineEdit()->text();
     if (buffer == strUserName)
     {
         // 登录成功


         
         //this->setResult(QDialog::Accepted);
         //this->close();
         this->done(QDialog::Accepted);
         ui.stackedWidget->setCurrentIndex(0);
     }
     else
     {
         if (m_socket->isOpen())
         {
             m_socket->close();
         }

         QMessageBox msgbox(this);
         msgbox.setWindowTitle("帐号或密码错误");
         msgbox.setText("无法登录的原因：\r\n1.帐号输入错误或不存在\r\n2.密码错误，请检查是否区分大小写");
         msgbox.setIcon(QMessageBox::Critical);
         msgbox.exec();
     }
 }

 void Login::socketTimeout()
 {
     if (m_socketTimer.isActive())
     {
          m_socketTimer.stop();
     }

     if (m_socket->isOpen())
     {
         m_socket->close();
     }

     QMessageBox msgbox(this);
     msgbox.setWindowTitle("超时");
     msgbox.setText("登录超时，请确认服务器是否可用！");
     msgbox.setIcon(QMessageBox::Critical);
     msgbox.exec();
 }

 void Login::loadUsersData()
 {
     QSqlDatabase db =  QSqlDatabase::addDatabase("QSQLITE", "default");
     if (db.isValid())
     {
         db.setDatabaseName("./database.db");
         if (db.open())
         {
             QSqlQuery query(db);
             if (query.exec("SELECT uid, account, password, nickname, status, portrait  FROM Users ORDER BY id DESC"))
             {
                 while (query.next())
                 {
                     QVariant varUid = query.value("uid");
                     QVariant varAccount = query.value("account");
                     QVariant varNickname = query.value("nickname");
                     if (varUid.isValid() && varAccount.isValid() && varNickname.isValid())
                     {
                         QVariant varPassword = query.value("password");
                         QVariant varStatus = query.value("status");
                         QVariant varPortrait = query.value("portrait");

                         QListWidgetItem *listItem = new QListWidgetItem(m_listWidget);
                         listItem->setText(varAccount.toString());		// 账号
                         listItem->setData(Qt::UserRole + 1, varNickname);												// 昵称
                         listItem->setData(Qt::UserRole + 2, QPixmap(":/Resources/UserFace/face.jpg"));				// 头像(不能使用setIcon函数)
                         listItem->setData(Qt::UserRole + 3, varPassword);											// 密码
                         m_listWidget->addItem(listItem);
                     }
                 }
                 query.clear();
                 accountComboBoxItemChanged(0);  // 选中第一项
             }
#ifndef QT_NO_DEBUG
             else
             {
                 QSqlError error = query.lastError();
                 qDebug() <<  error.type() << error.databaseText() << error;
             }
#endif
             db.close();
         }
     }
 }

 void Login::saveUserData()
 {
     QSqlDatabase db =  QSqlDatabase::addDatabase("QSQLITE");
     if (db.isValid())
     {
         db.setDatabaseName("./database.db");
         if (db.open())
         {
             QSqlQuery query(db);
             // 删除原数据
             QString strUid = "123456";
             if (!strUid.isEmpty())
             {
                 QString strSqlDel = QString("DELETE FROM Users WHERE uid = %1").arg(strUid.toULongLong());
                 query.exec(strSqlDel);

                 QString strAccount = ui.accountComboBox->lineEdit()->text();
                 if (!strAccount.isEmpty())
                 {
                     QString strPassword = ui.rememberPwdCheck->isChecked() ? ui.passwordEdit->text() : "";
                     QString strNickname = ui.accountComboBox->currentData(Qt::UserRole + 1).toString();
                     // 插入新数据
                     QString strSqlIns = QString("INSERT INTO Users(uid, account, password, nickname, status, portrait, lasttime) VALUES(%1, '%2', '%3', '%4', %5, '%6', datetime('now', 'localtime'))")
                             .arg(strUid)
                             .arg(strAccount)
                             .arg(strPassword)     // 密码
                             .arg(strNickname)         // 昵称
                             .arg(0)            // 登录状态
                             .arg("QVariant()"); //QPixmap pixmap = qvariant_cast<QPixmap>(listItem->data(Qt::UserRole + 2));      // 头像
                     if (!query.exec(strSqlIns))
                     {
                         QSqlError error = query.lastError();
                         qDebug() << strSqlIns << error.databaseText() << error;
                     }
                 }
             }
         }
         db.close();
     }
 }

 void Login::setUserPortrait(QPixmap pixmap)
 {
     if (pixmap.isNull())
         pixmap = QPixmap(":/Resources/UserFace/face.jpg");

     if (pixmap.size() != QSize())
     {
         QPixmap mask(pixmap.size());
         QPainter maskPainter(&mask);
         maskPainter.fillRect(mask.rect(), Qt::white);
         maskPainter.setBrush(Qt::black);
         maskPainter.drawRoundedRect(mask.rect(), 10, 10);
         pixmap.setMask(mask.createMaskFromColor(Qt::white));
         ui.portraitLabel->setPixmap(pixmap);
     }
 }

 QTcpSocket* Login::socket()
 {
     return m_socket;
 }

